home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / asm.y next >
Text File  |  1993-03-08  |  6KB  |  267 lines

  1. /* Infix notation calculator--calc */
  2.  
  3. %{
  4. #define YYSTYPE char *
  5.  
  6. #include "asmtrans.h"
  7. %}
  8.  
  9. %token WORD
  10. %token WHITESP
  11. %token EOLN
  12. %token STRING
  13. %token DEFINECMD
  14. %token INCLUDECMD
  15. %token IFDEFCMD
  16. %token IFNDEFCMD
  17. %token ELSECMD
  18. %token ENDIFCMD
  19.  
  20. /* Grammar follows */
  21. %%
  22. input:
  23.         | input line
  24. ;
  25.  
  26. line:    EOLN        { emit($1); }
  27.         /* note that emit() will automatically free the memory,
  28.            and will also check the hidecnt variable */
  29.     | label EOLN    { emit($1); emit($2); }
  30.     | opline EOLN    { emit($1); emit($2); }
  31.     | label opline EOLN    { emit($1); emit($2);
  32.             emit($3); }
  33.     | INCLUDECMD WHITESP STRING EOLN { if (!hidecnt) do_include($3); free($3); }
  34.     | INCLUDECMD WHITESP WORD EOLN { if (!hidecnt) do_include($3); free($3); }
  35.     | DEFINECMD WHITESP WORD WHITESP STRING EOLN {
  36.         if (!hidecnt) do_define($3, $5); free($3); free($5); }
  37.     | DEFINECMD WHITESP WORD WHITESP operand EOLN {
  38.         if (!hidecnt) do_define($3, $5); free($3); free($5); }
  39.     | IFDEFCMD WHITESP WORD EOLN { do_ifdef($3); free($3); }
  40.     | IFNDEFCMD WHITESP WORD EOLN { do_ifndef($3); free($3); }
  41.     | ELSECMD EOLN { do_else(); }
  42.     | ENDIFCMD EOLN { do_endif(); } 
  43. ;
  44.  
  45. opline:    WHITESP opcode        { $$ = do_ops("", $2, "", ""); free($2); }
  46.     | WHITESP opcode WHITESP ops
  47.             { $$ = do_ops("", $2, $3, $4);
  48.              free($2); free($3); free($4); }
  49.     | WORD WHITESP opcode    { $$ = do_ops($1, $3, "", ""); free($1); free($3); }
  50.     | WORD WHITESP opcode WHITESP ops
  51.             { $$ = do_ops($1, $3, $4, $5);
  52.              free($1); free($3); free($4); free($5);}
  53. ;
  54.  
  55. ops: operand { $$ = $1; }
  56.     | operand ',' ops { $$ = concat3($1, ",", $3);
  57.                 free($1); free($3); }
  58. ;
  59.  
  60. opcode: WORD    { $$ = wordlookup($1); free($1); }
  61. ;
  62.  
  63. label: WORD ':' { $$ = concat($1, ":"); free($1); }
  64.  
  65. operand: basic    {$$ = $1; }
  66.     | '#' basic {$$ = immediate($2); free($2); }
  67.     | '(' basic ')' {$$ = indirect($2); free($2); }
  68.     | '(' basic ')' '+' {$$ = postinc($2); free($2); }
  69.     | '-' '(' basic ')' {$$ = predec($3); free($3); }
  70.     | basic '(' basic ')' {$$ = indexed($1, $3); free($1); free($3); }
  71.     | '(' basic ')' WORD {$$ = sizedop($2, $4); free($2); free($4); }
  72.     | basic '(' basic ',' basic ')' {$$ = twoindex($1, $3, $5);
  73.                 free($1); free($3); free($5); }
  74.     | basic '{' basic ':' basic '}' {$$ = bitfield($1, $3, $5);
  75.             free($1); free($3); free($5); }
  76. ;
  77.  
  78. basic: basexpr { $$ = $1; }
  79.     | basexpr op basic { $$ = concat3($1, $2, $3); free($1); free($2); free($3); }
  80.     | '-' basic { $$ = concat("-", $2); free($2); }
  81.  
  82. basexpr: WORD {$$ = wordlookup($1); free($1); }
  83.     | '$' WORD {$$ = hexop($2); free($2);}
  84. ;
  85.  
  86. op:     '+' { $$ = strdup("+"); }
  87.     | '-' { $$ = strdup("-"); }
  88.     | '*' { $$ = strdup("*"); }
  89.     | '/' { $$ = strdup("/"); }
  90. ;
  91. %%
  92. #include <setjmp.h>
  93.  
  94. jmp_buf start;
  95.  
  96. #ifdef NATIVEATARI
  97. #define STACK 32*1024L
  98. #ifdef LATTICE
  99. long _STACK = STACK;
  100. #endif
  101. #ifdef __GNUC__
  102. long _stksize = STACK;
  103. #endif
  104.  
  105. static void
  106. hit_return()
  107. {
  108.     printf("Hit return to continue\n");
  109.     fflush(stdout);
  110.     getchar();
  111. }
  112. #endif
  113.  
  114. void usage()
  115. {
  116.     fprintf(stderr, "Usage: asmtrans [-gas][-asm][-o outfile] infile\n");
  117.     exit(2);
  118. }
  119.  
  120. int errors = 0;
  121.  
  122. void
  123. do_include(file)
  124.     char *file;
  125. {
  126.     jmp_buf save;
  127.     FILE *oldin, *f;
  128.  
  129.     f = fopen(file, "r");
  130.     if (!f) {
  131.         perror(file);
  132.         return;
  133.     }
  134.     bcopy(start, save, sizeof(jmp_buf));
  135.     oldin = infile;
  136.     infile = f;
  137.     setjmp(start);
  138.     yyparse();
  139.     fclose(f);
  140.     infile = oldin;
  141.     bcopy(save, start, sizeof(jmp_buf));
  142.     longjmp(start,1);
  143. }
  144.  
  145. /* set up initial definitions based on syntax type */
  146.  
  147. void
  148. do_initial_defs()
  149. {
  150.     if (syntax == GAS) {
  151.         do_define("mmusr", "psr");
  152.         do_define("fpiar", "fpi");
  153.         do_define("XREF", ".globl");
  154.         do_define("XDEF", ".globl");
  155.         do_define("TEXT", ".text");
  156.         do_define("DATA", ".data");
  157.     /* gas doesn't have a .bss directive */
  158.         do_define("BSS", ".data");
  159.         do_define("END", "| END");
  160.         do_define("dc.l", ".long");
  161.         do_define("dc.w", ".word");
  162.         do_define("dc.b", ".byte");
  163.     } else if (syntax == ASM) {
  164.         do_define("TEXT", "SECTION TEXT");
  165.         do_define("DATA", "SECTION DATA");
  166.         do_define("BSS", "SECTION BSS");
  167.     }
  168. }
  169.  
  170. int
  171. main (argc, argv)
  172.     int argc; char **argv;
  173. {
  174.     FILE *f;
  175. #ifdef NATIVEATARI
  176.     if (!argv[0] || !argv[0][0])    /* run from desktop? */
  177.         atexit(hit_return);
  178. #endif
  179.     argv++;
  180.     outfile = stdout;
  181.  
  182.     while (*argv) {
  183.         if (!strcmp(*argv, "-o")) {
  184.             argv++;
  185.             if (*argv == 0) {
  186.                 fprintf(stderr, "missing argument to -o\n");
  187.                 usage();
  188.             }
  189.             f = fopen(*argv, "w");
  190.             if (!f)
  191.                 perror(*argv);
  192.             else
  193.                 outfile = f;
  194.             argv++;
  195.         } else if (!strcmp(*argv, "-gas")) {
  196.             argv++;
  197.             syntax = GAS;
  198.         } else if (!strcmp(*argv, "-asm")) {
  199.             argv++;
  200.             syntax = ASM;
  201.         } else if (!strcmp(*argv, "-purec")) {
  202.             argv++;
  203.             syntax = PUREC;
  204.         } else if (!strncmp(*argv, "-D", 2)) {
  205.             char *word, *defn;
  206.             word = *argv+2;
  207.             defn = index(word,'=');
  208.             if (defn)
  209.                 *defn++ = '\0';
  210.             else
  211.                 defn = "1";
  212.             if (*word) do_define(word,defn);
  213.             argv++;
  214.         } else if (!strcmp(*argv, "--")) {
  215.             argv++;
  216.             break;
  217.         } else {
  218.             if (**argv == '-') {
  219.                 fprintf(stderr, "unknown option: %s\n",
  220.                     *argv);
  221.                 usage();
  222.             }
  223.             break;
  224.         }
  225.     }
  226.  
  227.     do_initial_defs();
  228.  
  229.     if (*argv == 0) {
  230.         setjmp(start);
  231.         infile = stdin;
  232.         yyparse();
  233.     } else {
  234.         while(*argv) {
  235.         if (!(f = fopen(*argv, "r")))
  236.             perror(*argv);
  237.         else {
  238.             infile = f;
  239.             setjmp(start);
  240.             yyparse();
  241.             fclose(f);
  242.         }
  243.         argv++;
  244.         }
  245.     }
  246.  
  247.     if (ifstkptr != 0) {
  248.         fputs("%ifdef without matching %endif\n", stderr);
  249.         errors++;
  250.     }
  251.     return errors;
  252. }
  253.  
  254. void
  255. yyerror (s)  /* Called by yyparse on error */
  256.      char *s;
  257. {
  258.     errors++;
  259.     printf("%s\n", s);
  260.     longjmp(start, 1);
  261. }
  262.  
  263. void dbgmsg(s) char *s;
  264. {
  265.     fprintf(stderr, "%s\n", s);
  266. }
  267.